/**
 * 测试1301装备查询指令脚本
 * 验证装备基础数据查询是否返回标准格式
 */

const http = require('http');
const WebSocket = require('ws');

// 测试配置
const CONFIG = {
  server: {
    host: 'localhost',
    port: 3000,
    protocol: 'http'
  },

  // 测试用户信息
  testUser: {
    mobile: '17091271111',
    password: '123456',
    passwordHash: 'e10adc3949ba59abbe56e057f20f883e' // 123456的SHA256
  }
};

class Equipment1301Tester {
  constructor() {
    this.token = null;
    this.userId = null;
    this.ws = null;
    this.testResults = [];
  }

  // 运行完整测试流程
  async runTest() {
    console.log('🚀 开始1301装备查询指令测试...\n');
    console.log('测试目标：HTTP登录 → WebSocket连接 → 测试各种装备查询参数\n');

    try {
      // 1. HTTP登录
      await this.testHttpLogin();

      // 2. 建立WebSocket连接
      await this.testWebSocketConnection();

      // 3. 测试各种装备查询
      await this.testEquipmentQueries();

      // 4. 断开连接
      await this.testDisconnect();

      // 输出测试结果
      this.printTestResults();

    } catch (error) {
      console.error('❌ 测试过程中发生错误:', error.message);
      this.addTestResult('整体测试', false, error.message);
    }
  }

  // 1. HTTP登录测试
  async testHttpLogin() {
    console.log('🔐 步骤1: HTTP登录测试...');

    try {
      // 首先尝试注册用户（如果不存在）
      await this.registerUser();

      // 执行登录
      const loginData = await this.makeHttpRequest('/user-service/user/login', 'POST', {
        mobile: CONFIG.testUser.mobile,
        pwd: CONFIG.testUser.passwordHash
      });

      if (loginData.code === 0 && loginData.data) {
        this.userId = 2001;
        this.token = loginData.data.accessToken;

        console.log(`✅ 登录成功: userId=${this.userId}, token=${this.token.substring(0, 8)}...`);
        this.addTestResult('HTTP登录', true, `用户ID: ${this.userId}`);
      } else {
        throw new Error(`登录失败: ${loginData.msg || '未知错误'}`);
      }

    } catch (error) {
      console.log('❌ 登录失败:', error.message);
      this.addTestResult('HTTP登录', false, error.message);
      throw error;
    }
  }

  // 注册用户（如果不存在）
  async registerUser() {
    try {
      const res = await this.makeHttpRequest('/user-service/user/register', 'POST', {
        mobile: CONFIG.testUser.mobile,
        pwd: CONFIG.testUser.passwordHash,
        captcha: '123456' // 模拟验证码
      });
      console.log('📝 用户注册成功', res);
    } catch (error) {
      // 如果用户已存在，忽略错误
      if (error.message.includes('MOBILE_EXISTS') || error.message.includes('已存在')) {
        console.log('👤 用户已存在，跳过注册');
      } else {
        console.log('⚠️ 注册失败:', error.message);
      }
    }
  }

  // 2. WebSocket连接测试
  async testWebSocketConnection() {
    console.log('\n🔌 步骤2: WebSocket连接测试...');

    return new Promise((resolve, reject) => {
      try {
        const wsUrl = `ws://${CONFIG.server.host}:${CONFIG.server.port}/user-service/websocket?t=${this.token}`;
        this.ws = new WebSocket(wsUrl);

        this.ws.on('open', async () => {
          console.log('✅ WebSocket连接成功');
          this.addTestResult('WebSocket连接', true, '连接建立成功');

          // 设置消息监听器
          this.setupMessageHandler();

          // 等待连接完全稳定
          await this.delay(500);
          resolve();
        });

        this.ws.on('error', (error) => {
          console.log('❌ WebSocket连接失败:', error.message);
          this.addTestResult('WebSocket连接', false, error.message);
          reject(error);
        });

        this.ws.on('close', () => {
          console.log('🔌 WebSocket连接已关闭');
        });

        // 连接超时
        setTimeout(() => {
          if (this.ws.readyState === WebSocket.CONNECTING) {
            this.ws.close();
            reject(new Error('连接超时'));
          }
        }, 10000);

      } catch (error) {
        reject(error);
      }
    });
  }

  // 设置消息处理器
  setupMessageHandler() {
    this.ws.on('message', (data) => {
      try {
        const message = JSON.parse(data.toString());
        console.log('📨 收到消息:', JSON.stringify(message, null, 2));
      } catch (error) {
        console.error('❌ 消息解析失败:', error.message);
      }
    });
  }

  // 3. 测试各种装备查询
  async testEquipmentQueries() {
    console.log('\n⚔️ 步骤3: 测试装备查询...');

    // 测试用例
    const testCases = [
      { name: '武器类型(type=2, base=0)', params: { type: 2, base: 0, pageNum: 0 } },
      { name: '防具类型(type=3, base=0)', params: { type: 3, base: 0, pageNum: 0 } },
      { name: '项链类型(type=4, base=0)', params: { type: 4, base: 0, pageNum: 0 } },
      { name: '护腕类型(type=5, base=0)', params: { type: 5, base: 0, pageNum: 0 } },
      { name: '头盔类型(type=1, base=0)', params: { type: 1, base: 0, pageNum: 0 } },
      { name: '鞋子类型(type=6, base=0)', params: { type: 6, base: 0, pageNum: 0 } },
      { name: '武器-锤子(base=1)', params: { type: 2, base: 1, pageNum: 0 } },
      { name: '武器-斧头(base=2)', params: { type: 2, base: 2, pageNum: 0 } },
      { name: '武器-针类(base=3)', params: { type: 2, base: 3, pageNum: 0 } },
      { name: '武器-剑类(base=4)', params: { type: 2, base: 4, pageNum: 0 } },
      { name: '武器-刀类(base=5)', params: { type: 2, base: 5, pageNum: 0 } },
      { name: '防具-甲类(base=1)', params: { type: 3, base: 1, pageNum: 0 } },
      { name: '防具-血衣(base=2)', params: { type: 3, base: 2, pageNum: 0 } },
      { name: '防具-精衣(base=3)', params: { type: 3, base: 3, pageNum: 0 } },
      { name: '防具-速衣(base=4)', params: { type: 3, base: 4, pageNum: 0 } },
      { name: '防具-均衣(base=5)', params: { type: 3, base: 5, pageNum: 0 } },
      { name: '头盔-武士(base=1)', params: { type: 1, base: 1, pageNum: 0 } },
      { name: '头盔-文人(base=2)', params: { type: 1, base: 2, pageNum: 0 } },
      { name: '头盔-异师(base=3)', params: { type: 1, base: 3, pageNum: 0 } }
    ];

    for (const testCase of testCases) {
      await this.testSingleEquipmentQuery(testCase.name, testCase.params);
      await this.delay(1000); // 避免请求过快
    }
  }

  // 测试单个装备查询
  async testSingleEquipmentQuery(testName, params) {
    console.log(`\n🔍 测试: ${testName}`);

    if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
      this.addTestResult(testName, false, 'WebSocket未连接');
      return;
    }

    return new Promise((resolve) => {
      let responseReceived = false;

      // 设置响应监听器
      const responseHandler = (data) => {
        try {
          const message = JSON.parse(data.toString());
          if (message.act_id === 1301) {
            this.ws.removeListener('message', responseHandler);
            responseReceived = true;

            if (message.code === 0) {
              console.log(`✅ ${testName} 查询成功`);
              console.log(`📊 返回装备数量: ${message.list ? message.list.length : 0}`);
              console.log(`📄 当前页: ${message.page || 1}`);
              console.log(`📊 总装备数: ${message.total || 0}`);

              // 验证数据格式
              if (message.list && Array.isArray(message.list) && message.list.length > 0) {
                const sample = message.list[0];
                const hasRequiredFields = sample.id && sample.lvl && sample.name && sample.price !== undefined;
                
                if (hasRequiredFields) {
                  console.log(`✅ 数据格式验证通过`);
                  console.log(`📋 样本数据: ID=${sample.id}, 等级=${sample.lvl}, 名称=${sample.name}, 价格=${sample.price}`);
                  
                  // 验证价格计算
                  const expectedPrice = 1500 * Math.pow(2, sample.lvl - 1);
                  if (sample.price === expectedPrice) {
                    console.log(`✅ 价格计算正确: ${sample.price} = 1500 * 2^${sample.lvl - 1}`);
                  } else {
                    console.log(`❌ 价格计算错误: 实际=${sample.price}, 期望=${expectedPrice}`);
                  }
                  
                  this.addTestResult(testName, true, `返回${message.list.length}个装备，格式正确`);
                } else {
                  console.log(`❌ 数据格式验证失败，缺少必需字段`);
                  this.addTestResult(testName, false, '数据格式错误');
                }
              } else {
                console.log(`📭 该分类下没有装备`);
                this.addTestResult(testName, true, '查询成功，但无装备数据');
              }
            } else {
              console.log(`❌ ${testName} 查询失败: ${message.msg || '未知错误'}`);
              this.addTestResult(testName, false, message.msg || '查询失败');
            }
            resolve();
          }
        } catch (error) {
          console.error(`❌ ${testName} 响应解析失败:`, error.message);
          this.ws.removeListener('message', responseHandler);
          this.addTestResult(testName, false, '响应解析失败');
          resolve();
        }
      };

      this.ws.on('message', responseHandler);

      // 发送1301请求
      const requestData = {
        c: 1301,
        d: params
      };

      console.log(`📤 发送1301请求:`, JSON.stringify(requestData, null, 2));
      this.ws.send(JSON.stringify(requestData));

      // 设置超时
      setTimeout(() => {
        if (!responseReceived) {
          this.ws.removeListener('message', responseHandler);
          this.addTestResult(testName, false, '请求超时');
          resolve();
        }
      }, 10000);
    });
  }

  // 4. 断开连接
  async testDisconnect() {
    console.log('\n🔌 步骤4: 断开WebSocket连接...');
    if (this.ws) {
      this.ws.close();
    }
    this.addTestResult('断开连接', true, '连接已断开');
  }

  // 添加测试结果
  addTestResult(testName, success, message) {
    this.testResults.push({
      test: testName,
      success: success,
      message: message,
      timestamp: new Date().toISOString()
    });
  }

  // 打印测试结果
  printTestResults() {
    console.log('\n📊 测试结果汇总:');
    console.log('='.repeat(60));

    let successCount = 0;
    let totalCount = this.testResults.length;

    this.testResults.forEach((result, index) => {
      const status = result.success ? '✅' : '❌';
      console.log(`${index + 1}. ${status} ${result.test}: ${result.message}`);
      if (result.success) successCount++;
    });

    console.log('='.repeat(60));
    console.log(`总计: ${successCount}/${totalCount} 项测试通过`);

    if (successCount === totalCount) {
      console.log('🎉 所有测试通过！');
    } else {
      console.log('⚠️  部分测试失败，请检查日志');
    }
  }

  // HTTP请求工具方法
  async makeHttpRequest(path, method = 'GET', data = null) {
    return new Promise((resolve, reject) => {
      const options = {
        hostname: CONFIG.server.host,
        port: CONFIG.server.port,
        path: path,
        method: method,
        headers: {
          'Content-Type': 'application/json',
        }
      };

      if (data) {
        const postData = JSON.stringify(data);
        options.headers['Content-Length'] = Buffer.byteLength(postData);
      }

      const req = http.request(options, (res) => {
        let body = '';

        res.on('data', (chunk) => {
          body += chunk;
        });

        res.on('end', () => {
          try {
            const responseData = JSON.parse(body);
            if (res.statusCode >= 200 && res.statusCode < 300) {
              resolve(responseData);
            } else {
              reject(new Error(`HTTP ${res.statusCode}: ${responseData.message || body}`));
            }
          } catch (error) {
            if (res.statusCode >= 200 && res.statusCode < 300) {
              resolve(body);
            } else {
              reject(new Error(`HTTP ${res.statusCode}: ${body}`));
            }
          }
        });
      });

      req.on('error', (error) => {
        reject(error);
      });

      if (data) {
        req.write(JSON.stringify(data));
      }

      req.end();
    });
  }

  // 延迟函数
  async delay(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// 运行测试
async function main() {
  const tester = new Equipment1301Tester();
  await tester.runTest();
}

// 如果直接运行此脚本
if (require.main === module) {
  main().catch((error) => {
    console.error('💥 测试脚本执行失败:', error.message);
    process.exit(1);
  });
}

module.exports = Equipment1301Tester;
